package xyz.xtt.exchange.service.impl;

import java.util.HashSet;
import java.util.Map;
import java.util.Objects;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;

import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.exchange.constants.AssetTypeEnum;
import xyz.xtt.exchange.constants.DealStateEnum;
import xyz.xtt.exchange.constants.ErrorMessage;
import xyz.xtt.exchange.constants.OrderTypeEnum;
import xyz.xtt.exchange.constants.PayUnitEnum;
import xyz.xtt.exchange.constants.SellPatternEnum;
import xyz.xtt.exchange.entity.TblAsset;
import xyz.xtt.exchange.entity.TblAssetTransaction;
import xyz.xtt.exchange.entity.TblUserChainAccount;
import xyz.xtt.exchange.exception.ChainException;
import xyz.xtt.exchange.mapper.TblAssetTransactionMapper;
import xyz.xtt.exchange.response.OrderResponse;
import xyz.xtt.exchange.service.ITblAssetService;
import xyz.xtt.exchange.service.TblAssetTransactionService;
import xyz.xtt.exchange.service.ITblUserChainAccountService;

/**
 * <p>
 * 资产交易记录表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-10-23
 */
@Slf4j
@Service
public class TblAssetTransactionServiceImpl extends ServiceImpl<TblAssetTransactionMapper, TblAssetTransaction>
		implements TblAssetTransactionService {
	@Autowired
	private ITblAssetService iTblAssetService;
	@Autowired
	private ITblUserChainAccountService iTblUserChainAccountService;

	@Transactional(rollbackFor = Exception.class)
	public OrderResponse order(String uid, Long assetId) {
		TblAsset asset = iTblAssetService.orderQueryAsset(assetId);
		if (Objects.isNull(asset)) {
			throw new ChainException(ErrorMessage.ASSET_NOT_EXIST);
		}
		TblAssetTransaction queryOrder = queryOrder(uid, assetId);
		if (Objects.nonNull(queryOrder)) {
			throw new ChainException(ErrorMessage.USER_ORDER_NOT_PAY);
		}
		TblAssetTransaction calcOrder = calcOrder(asset, Longs.tryParse(uid));
		if (Objects.isNull(calcOrder)) {
			return null;
		}
		PayUnitEnum payClass = PayUnitEnum.queryConvert(asset.getUnit());
		AssetTypeEnum goodsType = AssetTypeEnum.queryConvert(asset.getFirstType());
		SellPatternEnum pricingMode = SellPatternEnum.queryConvert(asset.getSellPattern());
		this.save(calcOrder);
		return OrderResponse
				.builder()
				.orderId(calcOrder.getOrderId())
				.assetId(assetId)
				.sellUserId(calcOrder.getSellerUserId())
				.buyUserId(calcOrder.getBuyerUserId())
				.payClass(payClass.name())
				.thirdCode(asset.getGoodsId())
				.goodsType(goodsType.name())
				.pricingMode(pricingMode.name())
				.build();
	}

	/**
	 * 查询对于当前资产是否有未支付订单
	 * 
	 * @return
	 */
	private TblAssetTransaction queryOrder(String uid, Long assetId) {
		LambdaQueryChainWrapper<TblAssetTransaction> query = new LambdaQueryChainWrapper<>(baseMapper);
		return query
				.eq(TblAssetTransaction::getBuyerUserId, uid)
				.eq(TblAssetTransaction::getAssetId, assetId)
				.eq(TblAssetTransaction::getDealState, DealStateEnum.NOT_PAYED.code())
				.one();
	}

	private TblAssetTransaction calcOrder(TblAsset asset, Long buyerUserId) {
		Long ownerId = Longs.tryParse(asset.getOwnerId());
		HashSet<Long> users = Sets.newHashSet();
		users.add(ownerId);
		users.add(buyerUserId);
		// 查询用户的链帐户信息
		Map<Long, TblUserChainAccount> queryAfterAddUserMap = iTblUserChainAccountService.queryAfterAdd(users);
		// 买卖双方的用户必须存在
		if (queryAfterAddUserMap.containsKey(ownerId) && queryAfterAddUserMap.containsKey(buyerUserId)) {
			TblUserChainAccount sellUser = queryAfterAddUserMap.get(ownerId);
			TblUserChainAccount buyUser = queryAfterAddUserMap.get(buyerUserId);
			TblAssetTransaction build = TblAssetTransaction
					.builder()
					.orderId(IdUtil.getSnowflakeNextId())
					.assetId(asset.getId())
					.sellerUserId(String.valueOf(ownerId))
					.sellerChainAccount(sellUser.getChainAccount())
					.buyerUserId(String.valueOf(buyerUserId))
					.buyerChainAccount(buyUser.getChainAccount())
					.dealState(DealStateEnum.NOT_PAYED.code())
					.dealCreateDatetime(System.currentTimeMillis())
					.dealFinishDatetime(System.currentTimeMillis())
					.playCreateOrderDatetime(System.currentTimeMillis())
					// .payState(DealStateEnum.PAID.code())
					.orderType(OrderTypeEnum.NORMAL.code())
					.price(asset.getPrice())
					.goodsId(asset.getGoodsId())
					.sellPattern(SellPatternEnum.NORMAL.code())
					.unit(asset.getUnit())
					.build();
			return build;
		} else {
			log.info("ownerId {} or buyUserId: {} no exist", ownerId, buyerUserId);
		}
		return null;
	}
}
